﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using BLL.Utils;
using DAL.Clipboard;
using DAL.File;
using FileAccess = DAL.File.FileAccess;

namespace BLL.Model
{
    public class ProfileManager
    {
        private const string ProfileFile = "profile.xml.enc";
        private const string SyncDir = "ClipboardSync\\";
        public string ProfilePath { get; private set; }
        public string Username { get; private set; }
        private string Password { get; set; }
        public IFileAccess FileAccess { get; private set; }
        public Profile Profile { get; private set; }

        public string SyncPath
        {
            get { return ProfilePath + Username + "\\" + SyncDir; }
        }

        public string UserPath
        {
            get { return ProfilePath + Username + "\\" + ProfileFile; }
        }

        private string EncPass
        {
            get
            {
                return Profile == null ? null : Profile.UseEncryption ? Password : null;
            }
        }

        public static ProfileManager Create(string profilePath, string username, string pass, IFileAccess fs, bool isNew)
        {
            var pm = new ProfileManager
            {
                ProfilePath = profilePath,
                Username = username,
                Password = pass,
                FileAccess = fs,
            };

            if (isNew)
            {
                pm.Profile = new Profile();
                pm.Save();
                return pm;
            }
            else
            {
                var success = pm.Load();
                return success ? pm : null;
            }
        }

        public static string[] GetUsernames(string profilePath, FileAccess fs)
        {
            return fs.GetFolderContents(profilePath, true);
        }

        public bool Load()
        {
            var inputBytes = FileAccess.ReadFile(UserPath);
            if (inputBytes == null)
                return false;

            try
            {
                var outputBytes = PassEncHelper.DecryptData(Password, inputBytes);
                Profile = Misc.Deserialize<Profile>(outputBytes);
                return Profile != null;
            }
            catch
            {
                return false;
            }
        }

        public void Save()
        {
            var outputBytes = Misc.Serialize(Profile);
            outputBytes = PassEncHelper.EncryptData(Password, outputBytes);

            FileAccess.WriteFile(UserPath, outputBytes);
        }

        public void SaveContent(ClipboardContent content)
        {
            var path = SyncPath + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss.ffff") + @"\";
            // Set content's path for identifying!
            content.Path = path;

            SerHelper.SaveContent(content, FileAccess, path, EncPass);
        }

        public ClipboardContent LoadContent(string parentPath)
        {
            return SerHelper.LoadContent(FileAccess, parentPath, EncPass);
        }

        public ClipboardContent[] LoadOldContents(int count)
        {
            var ret = new List<ClipboardContent>();
            var clipboardFolders = FileAccess.GetFolderContents(SyncPath, true).OrderByDescending(folder =>
            {
                DateTime time;
                var dirName = Path.GetFileName(folder);
                var success = DateTime.TryParseExact(dirName, "yyyy-MM-dd HH-mm-ss.ffff",
                    CultureInfo.InvariantCulture, DateTimeStyles.None, out time);
                return success ? time : DateTime.Now;
            }).Take(count).ToArray();

            foreach (var folder in clipboardFolders)
            {
                var content = SerHelper.LoadContent(FileAccess, folder + "\\", EncPass);
                if (content != null)
                    ret.Add(content);
            }

            return ret.ToArray();
        }
    }
}